package com.hbut.common.security.service;

import cn.hutool.core.lang.UUID;
import com.hbut.common.core.constants.CacheConstants;
import com.hbut.common.core.constants.JwtConstants;
import com.hbut.common.core.domain.LoginUser;
import com.hbut.common.core.utils.JwtUtils;
import com.hbut.common.redis.service.RedisService;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Service
@Slf4j
public class TokenService {
    @Autowired
    private RedisService redisService;

    public String createToken(Long userid, Integer identity, String secret, String nickname,String headImage) {
        // 登录成功
        Map<String, Object> claims = new HashMap<>();
        String userKey = UUID.fastUUID().toString();
        claims.put(JwtConstants.LOGIN_USER_ID,userid);
        claims.put(JwtConstants.LOGIN_USER_KEY,userKey);
        String token = JwtUtils.createToken(claims, secret);
        String key = getTokenKey(userKey);
        LoginUser loginUser = new LoginUser();
        loginUser.setIdentity(identity);
        loginUser.setNickName(nickname);
        loginUser.setHeadImage(headImage);
        redisService.setCacheObject(key, loginUser,CacheConstants.EXP, TimeUnit.MINUTES);
        return token;
    }

    //延长 token 的有效时间,就是延长 redis 中 储存的用于用户身份认证的敏感信息的有效时间
    public void extendToken(Claims claims) {

        String key = getTokenKey(getUserKey(claims));
        //获取当前用户的token 的有效时间
        Long expire = redisService.getExpire(key, TimeUnit.MINUTES);
        //如果当前用户的token 已经过期了，那么就延长它
        if(expire != null && expire <CacheConstants.REFRESH_TIME){
            redisService.expire(key, CacheConstants.EXP, TimeUnit.MINUTES);
        }
    }
    public LoginUser getLoginUser(String token, String secret) {
        String userKey = getUserKey(token,secret);
        return redisService.getCacheObject(getTokenKey(userKey), LoginUser.class);
    }

    public boolean logout(String token, String secret) {
        String key = getTokenKey(getUserKey(token,secret));
        return redisService.deleteObject(key);
    }

    public String getUserKey(String token, String secret) {
        Claims claims = getClaims(token, secret);
        return JwtUtils.getUserKey(claims);
    }
    public String getUserKey(Claims claims) {
        return JwtUtils.getUserKey(claims);
    }
    public Long getUserId(Claims claims) {
        return Long.valueOf(JwtUtils.getUserId(claims));
    }

    private String getTokenKey(String userKey) {
        return CacheConstants.LOGIN_TOKEN_KEY + userKey;
    }

    public  Claims getClaims(String token, String secret) {
        Claims claims = null;
        try {
            claims = JwtUtils.parseToken(token, secret);
            if(claims == null){
                log.error("解析 token:{}, 出现异常 !!", token);
            }
        } catch (Exception e) {
            log.error("解析 token:{}, 出现异常 !!", token,e);
        }
        return claims;
    }

}
